<template>
  <v-card>
    <v-card-title class="headline">批量上传视频</v-card-title>
    
    <v-alert v-if="selectedFiles.length === 0" type="info" variant="tonal" class="mx-4 my-2">
      请选择视频文件进行批量上传，可以拖拽文件到上传区域或点击"选择多个视频"按钮。
    </v-alert>

    <v-alert v-if="selectedFiles.length > 0" type="success" variant="tonal" class="mx-4 my-2">
      已选择 {{ selectedFiles.length }} 个视频文件。选择后可以点击每个视频右侧的<v-icon size="small" color="info">mdi-pencil</v-icon>按钮编辑视频信息。
    </v-alert>

    <v-card-text>
      <v-row>
        <v-col cols="12" md="6">
          <v-card border="dashed" min-height="300px" class="ma-2" variant="outlined" style="text-align: center;" 
            @dragover.prevent 
            @drop.prevent="handleFileDrop"
          >
            <v-list density="compact" style="margin: 0 auto;">
              <v-list-item>
                <v-icon color="blue" :size="50">mdi-upload-multiple</v-icon>
              </v-list-item>
              <v-list-item>
                <v-card-subtitle>拖到此处或点击下方按钮选择视频</v-card-subtitle>
              </v-list-item>
              <v-list-item>
                <v-btn color="primary" @click="videoFilesRef.click()">选择多个视频</v-btn>
              </v-list-item>
              <v-list-item>
                <v-chip class="ma-2 font-weight-bold" color="green" label>
                  <v-icon start icon="mdi-file-cloud-outline"></v-icon>
                  审核队列: {{ queueState }}
                </v-chip>
              </v-list-item>
            </v-list>
            <div style="display: none;">
              <form>
                <input v-on:change="handleFilesSelection" ref="videoFilesRef" type="file" accept="video/*" multiple />
              </form>
            </div>
          </v-card>
        </v-col>

        <v-col cols="12" md="6">
          <v-card class="ma-2" variant="outlined">
            <v-card-title>通用设置（可选）</v-card-title>
            <v-card-subtitle>设置通用参数后可一键应用到所有视频</v-card-subtitle>
            <v-card-text>
              <v-text-field v-model="commonSettings.titlePrefix" label="标题前缀" hint="将添加到每个视频文件名前"></v-text-field>
              <v-textarea v-model="commonSettings.description" label="视频描述" rows="3"></v-textarea>
              
              <v-autocomplete v-model="commonSettings.typeId" :items="allClassifyList" chips closable-chips
                color="blue-grey-lighten-2" item-title="name" item-value="id" label="视频分类" no-data-text="无视频分类">
                <template v-slot:chip="{ props, item }">
                  <v-chip v-bind="props" :prepend-icon="item.raw.icon || 'mdi-file-document-alert-outline'"
                    :text="item.raw.name"></v-chip>
                </template>
                <template v-slot:item="{ props, item }">
                  <v-list-item v-bind="props" :prepend-icon="item?.raw?.icon || 'mdi-file-document-alert-outline'"
                    :title="item?.raw?.name" :subtitle="item?.raw?.description || '无相关描述信息'"></v-list-item>
                </template>
              </v-autocomplete>
              
              <v-combobox v-model="commonSettings.labels" chips multiple label="视频标签" hint="输入标签后按回车键确认"></v-combobox>
              
              <v-btn color="primary" block class="mt-4" @click="applyCommonSettings">
                应用通用设置到所有视频
              </v-btn>
            </v-card-text>
          </v-card>
        </v-col>
      </v-row>

      <v-divider class="my-4"></v-divider>

      <v-card v-if="selectedFiles.length > 0">
        <v-card-title>已选择的视频文件 ({{ selectedFiles.length }}个)</v-card-title>
        
        <v-list>
          <v-list-item v-for="file in selectedFiles" :key="file.id" :value="file.id">
            <template v-slot:prepend>
              <v-icon :color="getStatusColor(file.status)" class="mr-2">
                {{ file.status === 'success' ? 'mdi-check-circle' : 
                   file.status === 'error' ? 'mdi-alert-circle' : 
                   file.status === 'uploading' ? 'mdi-upload' : 'mdi-file-video' }}
              </v-icon>
            </template>
            
            <v-list-item-title>{{ file.name }}</v-list-item-title>
            
            <v-list-item-subtitle>
              {{ formatFileSize(file.size) }} | 
              {{ getStatusText(file.status) }}
              <v-progress-linear
                v-if="file.status === 'uploading'"
                :model-value="file.progress || 0"
                height="5"
                color="primary"
                class="mt-1"
              ></v-progress-linear>
            </v-list-item-subtitle>
            
            <template v-slot:append>
              <v-btn
                icon
                size="small"
                color="info"
                class="mr-2"
                @click="openEditDialog(file)"
                :disabled="file.status === 'uploading'"
              >
                <v-icon>mdi-pencil</v-icon>
                <v-tooltip activator="parent" location="top">编辑视频信息</v-tooltip>
              </v-btn>
              <v-btn
                icon
                size="small"
                color="error"
                @click="removeFile(file)"
                :disabled="file.status === 'uploading'"
              >
                <v-icon>mdi-delete</v-icon>
                <v-tooltip activator="parent" location="top">移除</v-tooltip>
              </v-btn>
            </template>
          </v-list-item>
          
          <v-divider></v-divider>
          
          <v-list-item>
            <v-list-item-subtitle class="text-caption">
              <v-icon size="small" color="warning" class="mr-1">mdi-information</v-icon>
              请为每个视频设置标题、分类、标签和封面，然后点击"开始批量上传"按钮
            </v-list-item-subtitle>
            
            <template v-slot:append>
              <v-btn color="warning" variant="text" @click="clearAllFiles" class="mr-2">
                <v-icon start>mdi-delete-sweep</v-icon>
                清空所有
              </v-btn>
              <v-btn 
                color="primary" 
                @click="startBatchUpload" 
                :disabled="isUploading || selectedFiles.length === 0"
                :loading="isUploading"
              >
                <v-icon start>mdi-cloud-upload</v-icon>
                开始批量上传
              </v-btn>
            </template>
          </v-list-item>
        </v-list>
      </v-card>
    </v-card-text>

    <!-- 编辑视频信息对话框 -->
    <v-dialog v-model="editDialog" max-width="700px" persistent>
      <v-card v-if="editingFile">
        <v-card-title class="text-h5 bg-primary text-white">
          编辑视频信息: {{ editingFile.name }}
        </v-card-title>
        <v-card-text class="pt-4">
          <v-container>
            <v-row>
              <v-col cols="12">
                <v-text-field v-model="editingFile.videoInfo.title" label="视频标题" hide-details="auto" variant="outlined"></v-text-field>
              </v-col>
              <v-col cols="12">
                <v-textarea v-model="editingFile.videoInfo.description" label="视频描述" rows="3" hide-details="auto" variant="outlined"></v-textarea>
              </v-col>
              <v-col cols="12">
                <v-autocomplete v-model="editingFile.videoInfo.typeId" :items="allClassifyList" 
                  chips closable-chips color="blue-grey-lighten-2" item-title="name" 
                  item-value="id" label="视频分类" no-data-text="无视频分类" hide-details="auto" variant="outlined">
                  <template v-slot:chip="{ props, item }">
                    <v-chip v-bind="props" :prepend-icon="item.raw?.icon || 'mdi-file-document-alert-outline'"
                      :text="item.raw?.name"></v-chip>
                  </template>
                  <template v-slot:item="{ props, item }">
                    <v-list-item v-bind="props" :prepend-icon="item?.raw?.icon || 'mdi-file-document-alert-outline'"
                      :title="item?.raw?.name" :subtitle="item?.raw?.description || '无相关描述信息'"></v-list-item>
                  </template>
                </v-autocomplete>
              </v-col>
              <v-col cols="12">
                <v-combobox v-model="editingFile.videoInfo.labels" chips multiple label="视频标签" 
                  hint="输入标签后按回车键确认" hide-details="auto" variant="outlined"></v-combobox>
              </v-col>
              <v-col cols="12" class="d-flex justify-center">
                <v-card class="mb-2 mx-auto pt-2" height="180px" width="200px" :rounded="10" variant="outlined">
                  <v-card-title class="text-subtitle-1 text-center">
                    视频封面
                  </v-card-title>
                  <v-hover v-slot="{ isHovering, props }">
                    <div v-bind="props" class="d-flex justify-center align-center" style="height: 120px; position: relative;">
                      <v-img :key="editingFile.videoInfo.coverId" :src="editingFileCoverImg" height="100" width="160" cover class="rounded" />
                      <v-overlay :model-value="isHovering || editingUploading > -1" contained scrim="black"
                        class="align-center justify-center" @click="coverFileRef.click()">
                        <v-icon v-if="editingUploading == -1" color="white" size="large">mdi-camera</v-icon>
                        <v-progress-circular v-else :model-value="editingUploading" color="white"></v-progress-circular>
                        <div class="text-caption text-white">点击上传封面</div>
                      </v-overlay>
                    </div>
                  </v-hover>
                  <input hidden v-on:change="uploadEditingCover" ref="coverFileRef" type="file" accept="image/*" />
                </v-card>
              </v-col>
            </v-row>
          </v-container>
        </v-card-text>
        <v-divider></v-divider>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="error" variant="text" @click="closeEditDialog">取消</v-btn>
          <v-btn color="success" variant="text" @click="saveVideoInfo">保存</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-snackbar v-model="snackbar.show" :color="snackbar.color" :timeout="3000">
      {{ snackbar.text }}
      <template v-slot:actions>
        <v-btn color="white" variant="text" @click="snackbar.show = false">
          关闭
        </v-btn>
      </template>
    </v-snackbar>
  </v-card>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import { apiUploadFile } from '../../../apis/file';
import { apiGetAuditQueueState } from '../../../apis/video';
import { apiVideoPush } from '../../../apis/user/videoManger';
import { apiClassifyGetAll } from '../../../apis/classify';
import { apiFileGet } from '../../../apis/file';

const videoFilesRef = ref(null);
const coverFileRef = ref(null);
const uploading = ref(-1);
const editingUploading = ref(-1);
const allClassifyList = ref([]);
const queueState = ref("快速");
const isUploading = ref(false);
const editDialog = ref(false);
const editingFile = ref(null);

const selectedFiles = ref([]);
const commonSettings = ref({
  titlePrefix: '',
  description: '',
  typeId: null,
  labels: [],
});

const snackbar = ref({
  show: false,
  text: "",
  color: "success"
});

const tableHeaders = [
  { title: '文件名', key: 'name', sortable: true },
  { title: '大小', key: 'size', sortable: true },
  { title: '状态', key: 'status', sortable: true },
  { title: '进度', key: 'progress', sortable: false },
  { title: '操作', key: 'actions', sortable: false }
];

const editingFileCoverImg = computed(() => {
  if (!editingFile.value) return "/logo.png";
  
  if (coverFileRef.value && coverFileRef.value.files && coverFileRef.value.files[0]) {
    var URL = window.URL || window.webkitURL;
    return URL.createObjectURL(coverFileRef.value.files[0]);
  }
  
  if (editingFile.value.videoInfo.coverId) {
    return apiFileGet(editingFile.value.videoInfo.coverId);
  }
  
  return "/logo.png";
});

onMounted(() => {
  getQueueState();
  getClassifyList();
});

const getClassifyList = () => {
  apiClassifyGetAll().then(({ data }) => {
    if (!data.state) {
      allClassifyList.value = [];
      return;
    }
    allClassifyList.value = data.data;
  });
};

const getQueueState = () => {
  apiGetAuditQueueState().then(({ data }) => {
    if (!data.state) {
      return;
    }
    queueState.value = data.message;
  });
};

const handleFilesSelection = (event) => {
  const files = event.target.files;
  if (!files || files.length === 0) return;

  processFiles(Array.from(files));
  
  // 清空输入框以便再次选择相同文件
  videoFilesRef.value.value = "";
};

const handleFileDrop = (event) => {
  const droppedFiles = event.dataTransfer.files;
  if (!droppedFiles || droppedFiles.length === 0) return;
  
  processFiles(Array.from(droppedFiles));
};

const processFiles = (files) => {
  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    if (!isVideoFile(file.name)) {
      showSnackbar(`${file.name} 不是有效的视频文件`, 'error');
      continue;
    }
    
    // 检查文件是否已经添加
    const isDuplicate = selectedFiles.value.some(f => f.name === file.name && f.size === file.size);
    if (isDuplicate) {
      showSnackbar(`文件 ${file.name} 已存在`, 'warning');
      continue;
    }
    
    // 生成唯一ID
    const fileId = Date.now() + Math.floor(Math.random() * 1000) + i;
    
    // 添加到文件列表
    selectedFiles.value.push({
      id: fileId,
      file,
      name: file.name,
      size: file.size,
      status: 'pending', // pending, uploading, success, error
      progress: 0,
      url: null,
      subscription: null,
      videoInfo: {
        title: getFileNameWithoutExtension(file.name),
        description: '',
        typeId: null,
        labels: [],
        coverId: null
      }
    });
    
    showSnackbar(`已添加视频: ${file.name}`, 'success');
  }
};

const removeFile = (file) => {
  const index = selectedFiles.value.findIndex(f => f.id === file.id);
  if (index !== -1) {
    // 如果文件正在上传，先取消上传
    if (selectedFiles.value[index].subscription) {
      selectedFiles.value[index].subscription.unsubscribe();
    }
    selectedFiles.value.splice(index, 1);
  }
};

const clearAllFiles = () => {
  // 取消所有正在上传的文件
  selectedFiles.value.forEach(file => {
    if (file.subscription) {
      file.subscription.unsubscribe();
    }
  });
  selectedFiles.value = [];
};

const applyCommonSettings = () => {
  if (selectedFiles.value.length === 0) {
    showSnackbar("没有选择文件", "warning");
    return;
  }
  
  const confirmMsg = "确定将通用设置应用到所有视频？这将覆盖已设置的视频信息。";
  if (!confirm(confirmMsg)) return;
  
  selectedFiles.value.forEach(file => {
    if (commonSettings.value.titlePrefix) {
      file.videoInfo.title = commonSettings.value.titlePrefix + getFileNameWithoutExtension(file.name);
    }
    
    if (commonSettings.value.description) {
      file.videoInfo.description = commonSettings.value.description;
    }
    
    if (commonSettings.value.typeId) {
      file.videoInfo.typeId = commonSettings.value.typeId;
    }
    
    if (commonSettings.value.labels && commonSettings.value.labels.length > 0) {
      file.videoInfo.labels = [...commonSettings.value.labels];
    }
  });
  
  showSnackbar("通用设置已应用到所有视频", "success");
};

const openEditDialog = (file) => {
  editingFile.value = JSON.parse(JSON.stringify(file));
  // 确保labels是数组
  if (!Array.isArray(editingFile.value.videoInfo.labels)) {
    editingFile.value.videoInfo.labels = [];
  }
  editDialog.value = true;
};

const closeEditDialog = () => {
  editDialog.value = false;
  // 延迟清除编辑对象，以避免对话框关闭动画过程中出现的闪烁
  setTimeout(() => {
    editingFile.value = null;
  }, 300);
};

const saveVideoInfo = () => {
  if (!editingFile.value) return;
  
  const index = selectedFiles.value.findIndex(f => f.id === editingFile.value.id);
  if (index !== -1) {
    // 更新视频信息
    selectedFiles.value[index].videoInfo = editingFile.value.videoInfo;
    showSnackbar("视频信息已更新", "success");
  }
  
  closeEditDialog();
};

const uploadEditingCover = () => {
  if (!coverFileRef.value.files[0] || !editingFile.value) return;
  editingUploading.value = 0;
  
  apiUploadFile(coverFileRef.value.files[0], {
    next: (e) => {
      editingUploading.value = e.total.percent;
    },
    error: () => {
      editingUploading.value = -1;
      showSnackbar("封面上传失败", "error");
    },
    complete: (e, fileId) => {
      if (!fileId.state) {
        showSnackbar(fileId.message, "error");
        return;
      }
      editingUploading.value = -1;
      editingFile.value.videoInfo.coverId = fileId.data;
      showSnackbar("封面上传完成", "success");
      
      // 清除文件输入框的内容
      coverFileRef.value.value = null;
    }
  });
};

const startBatchUpload = async () => {
  // 验证所有视频信息是否完整
  const invalidFiles = selectedFiles.value.filter(file => 
    file.status !== 'success' && 
    (!file.videoInfo.typeId || !file.videoInfo.labels || file.videoInfo.labels.length === 0 || !file.videoInfo.coverId)
  );
  
  if (invalidFiles.length > 0) {
    const confirmMsg = `有${invalidFiles.length}个视频信息不完整（缺少分类、标签或封面），是否继续上传完整信息的视频？`;
    if (!confirm(confirmMsg)) return;
  }
  
  if (selectedFiles.value.length === 0) {
    showSnackbar("请选择要上传的视频文件", "error");
    return;
  }
  
  isUploading.value = true;
  let successCount = 0;
  let errorCount = 0;
  let skippedCount = 0;
  
  for (let i = 0; i < selectedFiles.value.length; i++) {
    const fileItem = selectedFiles.value[i];
    
    if (fileItem.status === 'success') {
      successCount++;
      continue;  // 跳过已成功上传的文件
    }
    
    if (fileItem.status === 'uploading') {
      continue;  // 跳过正在上传的文件
    }
    
    // 检查是否有完整信息
    if (!fileItem.videoInfo.typeId || !fileItem.videoInfo.labels || fileItem.videoInfo.labels.length === 0 || !fileItem.videoInfo.coverId) {
      skippedCount++;
      continue; // 跳过信息不完整的文件
    }
    
    // 更新状态为上传中
    fileItem.status = 'uploading';
    fileItem.progress = 0;
    
    try {
      await uploadVideoFile(fileItem);
      successCount++;
    } catch (error) {
      errorCount++;
      fileItem.status = 'error';
      console.error(`上传文件 ${fileItem.name} 失败:`, error);
    }
  }
  
  isUploading.value = false;
  
  let message = `批量上传完成，成功: ${successCount}, 失败: ${errorCount}`;
  if (skippedCount > 0) {
    message += `, 跳过: ${skippedCount}（信息不完整）`;
  }
  
  showSnackbar(message, successCount > 0 ? "success" : "error");
  getQueueState();
};

const uploadVideoFile = (fileItem) => {
  return new Promise((resolve, reject) => {
    fileItem.subscription = apiUploadFile(fileItem.file, {
      next: (e) => {
        fileItem.progress = e.total.percent;
      },
      error: (e) => {
        fileItem.status = 'error';
        reject(e);
      },
      complete: async (e, fileId) => {
        if (!fileId.state) {
          fileItem.status = 'error';
          reject(new Error(fileId.message));
          return;
        }
        
        fileItem.url = fileId.data;
        
        try {
          // 构建视频信息并保存
          const videoInfo = {
            title: fileItem.videoInfo.title,
            description: fileItem.videoInfo.description,
            url: fileItem.url,
            cover: fileItem.videoInfo.coverId,
            typeId: fileItem.videoInfo.typeId,
            labelNames: [...fileItem.videoInfo.labels],
            auditQueueStatus: queueState.value === "快速" ? true : false
          };
          
          const result = await apiVideoPush(videoInfo);
          if (result.data && result.data.state) {
            fileItem.status = 'success';
            resolve();
          } else {
            fileItem.status = 'error';
            reject(new Error(result.data?.message || '保存视频信息失败'));
          }
        } catch (error) {
          fileItem.status = 'error';
          reject(error);
        }
      }
    });
  });
};

const formatFileSize = (size) => {
  if (size < 1024) {
    return size + ' B';
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + ' KB';
  } else if (size < 1024 * 1024 * 1024) {
    return (size / (1024 * 1024)).toFixed(2) + ' MB';
  } else {
    return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
  }
};

const getStatusColor = (status) => {
  switch (status) {
    case 'pending': return 'grey';
    case 'uploading': return 'blue';
    case 'success': return 'green';
    case 'error': return 'red';
    default: return 'grey';
  }
};

const getStatusText = (status) => {
  switch (status) {
    case 'pending': return '等待上传';
    case 'uploading': return '上传中';
    case 'success': return '上传成功';
    case 'error': return '上传失败';
    default: return '未知状态';
  }
};

const showSnackbar = (text, color = 'success') => {
  snackbar.value = {
    show: true,
    text,
    color
  };
};

const isVideoFile = (filename) => {
  const ext = filename.split('.').pop().toLowerCase();
  return ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm'].includes(ext);
};

const getFileNameWithoutExtension = (filename) => {
  return filename.split('.').slice(0, -1).join('.');
};
</script> 